import * as THREE from 'three'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'
// 1. 引入 CubeTextureLoader 来加载立方体环境贴图
import { CubeTextureLoader } from 'three/src/loaders/CubeTextureLoader.js';
import { BackSide, BoxGeometry, InstancedMesh, Mesh, MeshLambertMaterial, MeshStandardMaterial, PointLight, Object3D } from 'three';

export const threes = {
  data() {
    return {
      baseUrl: window.config.baseUrl,
      cameras: null,
      planeTop: null,
      planeBottom: null,
      cylinder: null,
      scale: 0,
      translateX: 0,
      translate: 0,
      theWidth: 1,
      theHeight: 1,
      params: {
        // 存储参数
        topPlaneX: -0.68,
        topPlaneY: 1.5,
        topPlaneZ: -0.15,
        bottomPlaneX: -0.68,
        bottomPlaneY: 0.84,
        bottomPlaneZ: -0.15
      },
      geometryTop: null,
      geometryBottom: null,
      XianShuChuiZhiCeShiTong_1: null,
      ZhunZhiDuJianCeBan: null,
      PingBanTanCeQi: null,
      cameraOriginal: [-6.099, 1.356, 15.828],
      objectNames: [
      'TanCeQi4',
        'DR8_1',
        'BiJiBenDianNao1',
        'DH12'
      
      ],
      //气泡对应名称
      objectText: [
        {
          name: 'TanCeQi4',
          text:'TanCeQi4'
        },
        {
          name: 'DR8_1',
          text: 'DR8_1'
        },
        {
          name:"BiJiBenDianNao1",text:"BiJiBenDianNao1"
        },
        {
          name:'DH12',text:'DH12'
        }
       
      ],
      DR7_2: null,
      DH12:null,
      playIng: false,
      camera: null,
      scene: null,
      render: null,
      raycaster: null,
      mouse: null,
      objects: [],
      objectFather: null,
      action: null,
      andh: null,
      objectReItem: null,
      cjfiles: [
        'GengYiShi.glb','CTJianChaShi.glb','dating.glb'
      ],
       dhfiles: ['PT_CTJCJS_DuiHua.glb'],
      isDestroyed: false,
      animationFrameId: null,
      animations:[]
    }
  },

    created() {
      console.log('混入成功');
      
  },
  mounted() {},
  beforeDestroy() {
    this.clearAll()
  },
  watch: {
   
  },
  computed: {
    getPosition(){
      //根据返回的位置信息计算物品提示小标位
      let maincontWidth = this.$el.offsetWidth
      let maincontHeight = this.$el.offsetHeight
      let leftPercentage = ((this.tipPosition.x + 25) / maincontWidth) * 100
      let topPercentage = ((this.tipPosition.y - 30) / maincontHeight) * 100
      return 'left:' + leftPercentage + '%;top:' + topPercentage + '%;'
    }
  },
  methods: {
     clearAll() { 
        clearInterval(this.spriteTimer)
        this.spriteTimer = null

  
      try {
               // 清理所有定时器
      // clearTimeout()
       // 标记销毁，停止动画
        this.isDestroyed = true
      if (this.animationFrameId) {
        cancelAnimationFrame(this.animationFrameId)
        this.animationFrameId = null
      }
        //销毁sprite
          // this.clearPoint()
      // 停止所有动画
      if (typeof this.stopall === 'function') this.stopall()
      // 清理动画状态
      this.animationStatus = {}
      this.mixerMap = {}
      if (this.theMixer) {
        this.theMixer.stopAllAction()
        if (this.objectFather && this.objectFather.scene) {
          this.theMixer.uncacheRoot(this.objectFather.scene)
        }
        this.theMixer = null
      }
      if (this.action) {
        this.action.stop()
        this.action.reset()
        this.action = null
      }

      // 清理场景中的所有对象
      if (this.scene) {
        this.scene.traverse((child) => {
          if (child.isMesh) {
            if (child.geometry) child.geometry.dispose()
            if (child.material) {
              if (Array.isArray(child.material)) {
                child.material.forEach(material => {
                  if (material.map) material.map.dispose()
                  if (material.lightMap) material.lightMap.dispose()
                  if (material.bumpMap) material.bumpMap.dispose()
                  if (material.normalMap) material.normalMap.dispose()
                  if (material.specularMap) material.specularMap.dispose()
                  if (material.envMap) material.envMap.dispose()
                  material.dispose()
                })
              } else {
                if (child.material.map) child.material.map.dispose()
                if (child.material.lightMap) child.material.lightMap.dispose()
                if (child.material.bumpMap) child.material.bumpMap.dispose()
                if (child.material.normalMap) child.material.normalMap.dispose()
                if (child.material.specularMap) child.material.specularMap.dispose()
                if (child.material.envMap) child.material.envMap.dispose()
                child.material.dispose()
              }
            }
          }
          if (child.isLight) { // 添加对灯光的处理
      child.dispose(); // 释放灯光资源
          }
          if (child.texture) { 
            child.texture.dispose();
          }
        })
        this.scene.clear()
      }
      // 清理渲染器
      if (this.render) {
        this.render.dispose()
        this.render.forceContextLoss()
        // 清理WebGL上下文
        if (this.render.domElement) {
          const gl = this.render.domElement.getContext('webgl')
          if (gl) {
            const loseContext = gl.getExtension('WEBGL_lose_context')
            if (loseContext) loseContext.loseContext()
          }
        }
        // 移除DOM
        if (this.$el && this.render.domElement && this.$el.contains(this.render.domElement)) {
          this.$el.removeChild(this.render.domElement)
        }
        this.render = null
      }
      // 清理相机
      this.camera = null

      // 清理控制器
      if (this.controls && typeof this.controls.dispose === 'function') {
        this.controls.dispose()
      }
      this.controls = null
      // 清理射线检测器
      this.raycaster = null
      // 清理鼠标对象
      this.mouse = null
      // 清理时钟
      this.clock = null
      // 清理对象引用
      this.objects = []
      this.objectFather = null
      this.objectFatherscene = null
      this.model = null
    
      this.outlinePass = null
      this.composer = null
      // 移除事件监听器
      if (document.body) {
        document.body.removeEventListener('mousemove', this.onDocumentMouseMove)
        document.body.removeEventListener('mousedown', this.onDocumentMouseDown)
      }
      if (this.$el) {
        this.$el.removeEventListener('mouseup', this.onDocumentMouseUp)
      }
      if (window) {
        window.removeEventListener('resize', this.onWindowResize)
      }
      this.isDestroyed  = false
    } catch (e) {
      console.log('清理资源时发生错误:', e)
      
    }
    },
           // 立即停止所有正在播放的动画，并设置为播放完成状态
    stopall() {
   
if (!this.theMixer || !this.action) return;

// 检查动画是否正在播放
// .isRunning() 是 AnimationAction 的方法，用于判断动画是否处于播放状态
      if (this.action.isRunning()) {
  console.log('停止当前播放动画');
  // 设置动画结束后保持最后一帧
  this.action.clampWhenFinished = true;
  
  // 标记状态
  this.playIng = false;
  if (!this.animationStatus) this.animationStatus = {};
  if (this.action._clip && this.action._clip.name) {
    this.animationStatus[this.action._clip.name] = true;
  }

  // 跳转到最后一帧并暂停
  if (this.action._clip) {
    this.action.time = this.action._clip.duration;
    this.action.paused = true;
    this.theMixer.update(0); // 立即刷新到最后一帧
  }

  // 停止动画 启用他会导致恢复默认第一帧
  // this.action.stop();
} else {
  console.log('没有正在播放的动画，不执行停止操作');
}
    },
resetAllAnimations() {
  // 没有混合器或动画数据，直接返回
  if (!this.theMixer || !this.objectFather?.animations?.length) {
    console.log('没有可重置的动画');
    return;
  }

  // 重置状态管理
  this.animationStatus = {};
  this.playIng = false;
  this.action = null;

  // 遍历所有动画片段，统一重置（所有动画由同一个混合器管理）
  this.objectFather.animations.forEach(clip => {
    if (!clip || !clip.name) return; // 过滤无效片段

    const action = this.theMixer.clipAction(clip);
    action.reset(); // 重置动画状态
    action.time = 0; // 回到第一帧
    action.paused = true;
    action.stop();
    action.clampWhenFinished = false; // 取消最后一帧锁定
    action.setLoop(THREE.LoopRepeat); // 恢复默认循环
  });

  // 强制刷新混合器
  this.theMixer.update(0);
  console.log('所有动画已重置为初始状态');
},

    //初始化
      init() {
      
      this.initSence()
      this.raycaster = new THREE.Raycaster() // 设置光线拾取
      this.clock = new THREE.Clock()
      this.mouse = new THREE.Vector2()
    },
    //初始化相机
    initCeremar() {
      const camera = new THREE.PerspectiveCamera(
        50,
        window.innerWidth / window.innerHeight,
        0.01,
        10000
      )
      camera.position.set(
        this.cameraOriginal[0],
        this.cameraOriginal[1],
        this.cameraOriginal[2]
      )

      this.camera = camera
      this.scene.add(this.camera)
      this.cameras = this.camera
    //  this.move(
    //     [-4.116, 1.172,14.985],
    //     [-7.65 / 180, -67.58  / 180,-7.08  / 180]
    //  )
      //   this.move(
      //   [-3.136, 1.561,14.389],
      //   [-173.85/ 180, 61.70 / 180,174.58 / 180]
      // )
      this.move(
    [-2.318, 1.719, 1.902],
            [-33.79 / 180, -86.91 / 180, -33.75 / 180]
      )


  
  // 2. 俯视角相机（从上往下看）
  this.cameraTop = new THREE.PerspectiveCamera(
    60,  // 视角可以略大一些
    1,    // 先设置默认比例，后面会调整
    0.1, 
    2000
  );
  // 俯视角位置（根据场景大小调整高度）
  this.cameraTop.position.set(20, 20,20); // 假设场景中心在(0,0,0)
  this.cameraTop.lookAt(0, 0, 0); // 看向场景中心
      this.scene.add(this.cameraTop);
         // 2. 控制俯视角相机
// this.move(
//  [-13.286, 2.346, -4.534], // x轴方向远离场景，y轴略高避免贴地
//  [-90 / 180, 0 / 180, 0 / 180], // 旋转：侧视需要调整角度让相机看向场景中心
//   this.cameraTop // 指定操作俯视角相机
// );
    
  // 3. 侧视角相机（从侧面看，比如右侧）
  this.cameraSide = new THREE.PerspectiveCamera(
    60,
    1,
    0.1,
    2000
  );
  // 侧视角位置（右侧视角）
  this.cameraSide.position.set(20, 5, 0); // x轴方向远离场景
  this.cameraSide.lookAt(0, 0, 0); // 看向场景中心
      this.scene.add(this.cameraSide);

        // 3. 控制侧视角相机（例如从右侧观察）
      
// this.move(
//   [-13.286, 2.346, -4.534], // x轴方向远离场景，y轴略高避免贴地
//  [-90 / 180, 0 / 180, 0 / 180], // 旋转：侧视需要调整角度让相机看向场景中心
//   this.cameraSide // 指定操作侧视角相机
// );

      // 俯视角渲染器
  this.rendererTop = new THREE.WebGLRenderer({ antialias: true });
 
  document.getElementById('top-view').appendChild(this.rendererTop.domElement);
  
  // 侧视角渲染器
  this.rendererSide = new THREE.WebGLRenderer({ antialias: true });
 
  document.getElementById('side-view').appendChild(this.rendererSide.domElement);
    },
    //初始化场景
      initSence() {
        var scene = new THREE.Scene()
        // 背景色设为 null 或一个中性色，因为会被环境贴图覆盖
        scene.background = new THREE.Color(0xbbbbbb);
        this.scene = scene
        this.initCeremar()
        this.initRenderer()
        this.initCotronl()
        this.initPoint()
        this.initFile()
        // 定义系统内设自动灯光和自定义灯光开关 //后续增加根据模型自适应灯光模块
        const flag = true
        if (flag) {
          const environment = new RoomEnvironment();
          const pmremGenerator = new THREE.PMREMGenerator(this.render);
          pmremGenerator.compileEquirectangularShader();
          this.scene.environment = pmremGenerator.fromScene(environment, 0.04).texture;
          environment.dispose();
        } else { 
          this.initLight()//自定义灯光
          // 自动模型灯光需要根据模型设置包围盒 this.setupProceduralLights(gltf.scene); // 调用自动灯光设置功能
        }
        
        // 使用RoomEnvironment设置环境光照
        // this.initEnvironment()
        // this.scene.environment = pmremGenerator.fromScene(environment).texture;
        // environment.dispose();
    },
    // 自动设置灯光功能
    setupProceduralLights(model) {
      // 确保模型有包围盒
      const box = new THREE.Box3().setFromObject(model);
      const center = box.getCenter(new THREE.Vector3());
      const size = box.getSize(new THREE.Vector3());

      // 移除旧的程序化灯光（如果存在），避免重复添加
      this.scene.traverse(child => {
          if (child.userData.isProceduralLight) {
              this.scene.remove(child);
              if (child.target) this.scene.remove(child.target);
          }
      });

      // 1. 环境光：提供基础照明
      const ambientLight = new THREE.AmbientLight(0xffffff, 1); // 调整环境光强度
      ambientLight.userData.isProceduralLight = true;
      this.scene.add(ambientLight);

      // 2. 主平行光：从模型上方偏前的位置照射
      const mainLight = new THREE.DirectionalLight(0xffffff, 2); // 调整主光源强度
      mainLight.position.set(
          center.x + size.x * 0.8,
          center.y + size.y * 1.5,
          center.z + size.z * 0.8
      );
      mainLight.target.position.copy(center);
      mainLight.castShadow = true;
      mainLight.shadow.mapSize.width = 2048;
      mainLight.shadow.mapSize.height = 2048;
      mainLight.shadow.camera.near = 0.1;
      mainLight.shadow.camera.far = size.length() * 3; // 根据模型尺寸调整阴影距离
      mainLight.shadow.camera.left = -size.x * 1.5;
      mainLight.shadow.camera.right = size.x * 1.5;
      mainLight.shadow.camera.top = size.y * 1.5;
      mainLight.shadow.camera.bottom = -size.y * 1.5;
      mainLight.shadow.bias = -0.001; // 解决阴影痤疮问题
      mainLight.userData.isProceduralLight = true;
      this.scene.add(mainLight);
      this.scene.add(mainLight.target);

      // 3. 辅助平行光：从模型后方偏下位置补光
      const fillLight = new THREE.DirectionalLight(0xffffff, 0.6); // 调整辅助光源强度
      fillLight.position.set(
          center.x - size.x * 0.8,
          center.y + size.y * 0.5,
          center.z - size.z * 0.8
      );
      fillLight.target.position.copy(center);
      fillLight.castShadow = true; // 启用阴影投射
      fillLight.shadow.mapSize.width = 1024;
      fillLight.shadow.mapSize.height = 1024;
      fillLight.shadow.camera.near = 0.1;
      fillLight.shadow.camera.far = size.length() * 2;
      fillLight.shadow.camera.left = -size.x;
      fillLight.shadow.camera.right = size.x;
      fillLight.shadow.camera.top = size.y;
      fillLight.shadow.camera.bottom = -size.y;
      fillLight.shadow.bias = -0.001;
      fillLight.userData.isProceduralLight = true;
      this.scene.add(fillLight);
      this.scene.add(fillLight.target);

      console.log("程序化灯光已设置。");
    },
    //初始化渲染器
    initRenderer() {
      this.render = new THREE.WebGLRenderer({
        antialias: true
      })
      this.render.setPixelRatio(window.devicePixelRatio)
      this.render.setSize(window.innerWidth, window.innerHeight)
      
      // 4. 开启物理正确光照，这对于环境光照很重要
      this.render.physicallyCorrectLights = true;

      // 5. 设置色调映射和曝光，以匹配环境光
      //this.render.shadowMap.enabled = true
      //this.render.shadowMap.type = THREE.PCFSoftShadowMap
      // this.render.toneMapping = THREE.ACESFilmicToneMapping
      this.render.toneMappingExposure = 1; // 1.0 是一个很好的起点，可以根据需要微调
      this.render.outputColorSpace = THREE.SRGBColorSpace;
      this.$el.appendChild(this.render.domElement)
      window.addEventListener('resize', this.onWindowResize) //监听窗口变化

    
    },
    //根据屏幕尺寸变化自适应
    onWindowResize() {
      //浏览器窗口大小改变后重新计算
      this.maincontWidth = this.$el.offsetWidth
      this.maincontHeight = this.$el.offsetHeight
      this.maincontSc = this.maincontWidth / this.maincontHeight
      this.camera.aspect = this.maincontSc
      this.camera.updateProjectionMatrix()
      this.render.setSize(this.maincontWidth, this.maincontHeight)
    }, //鼠标移动6+射线拾取
    //初始化控制器
    initCotronl() {
      this.mouse = new THREE.Vector2() //获取鼠标 位置二维坐标信息
      document.body.addEventListener('mousemove', this.onDocumentMouseMove)
      document.body.addEventListener('mousedown', this.onDocumentMouseDown)
      this.$el.addEventListener('mouseup', this.onDocumentMouseUp)
    }, //初始化物体
//     initFile() {
//       this.$emit('loadingfn', true)
//       let gltfloader = new GLTFLoader()
//       this.app = gltfloader
//       const dracoLoader = new DRACOLoader()
//       // dracoLoader.setDecoderPath('/draco/')
//       dracoLoader.setDecoderPath(
//         dracoUrl
//       )
//       dracoLoader.preload()
//       gltfloader.setDRACOLoader(dracoLoader)
//       gltfloader.load(this.baseUrl + 'dating.glb', (gltf) => {
//         this.model = gltf.scene
//         this.objectReItem = gltf.scene
//         gltf.scene.position.set(0, 0, 0)
//         this.objects = []
//         gltf.scene.traverse((child) => {
//           if (child.isMesh) {
//             // 移除 emissiveMap，因为环境光会提供更好的效果
//             // child.material.emissiveMap = child.material.map
//             if (this.objectNames.includes(child.name)) {
//               //将需要检查到的模型放到objects
//               this.objects.push(child)
//               console.log('当前可以戳摸的模型', this.objects)
//             }
       
            
//             if (child.name == 'DR7_2') {
//               this.DR7_2 = child
//             }
//           }
//         })
//         this.scene.add(gltf.scene)
//         this.$emit('loadingfn', false)
//           this.initFileS(0)
// // this.setupProceduralLights(this.model); // 自动适配灯光测试 (已替换为RoomEnvironment) 
//         // this.$emit('loadingfn', false);
//         this.animate()
       
//       })
//     },
initFile() {
  this.$emit('loadingfn', true);
  this.loadedModels = []; // 存储所有加载完成的模型
  this.currentFileIndex = 0; // 当前加载的文件索引
  
  // 初始化GLTF加载器
  const gltfloader = new GLTFLoader();
  const dracoLoader = new DRACOLoader();

  dracoLoader.setDecoderPath(window.config.dracoUrl);
  dracoLoader.preload();
  gltfloader.setDRACOLoader(dracoLoader);
  this.app = gltfloader;
  
  // 开始递归加载场景文件
  this.loadNextFile(gltfloader);
},

loadNextFile(loader) {
  // 所有场景文件加载完成后，开始加载动画文件
  if (this.currentFileIndex >= this.cjfiles.length) {
    this.currentAnimationIndex = 0; // 初始化动画文件索引
    this.loadedAnimations = []; // 存储所有加载完成的动画
    this.loadNextAnimation(loader); // 开始加载动画文件
    return;
  }
  
  // 获取当前要加载的场景文件名
  const fileName = this.cjfiles[this.currentFileIndex];
  const fileUrl = this.baseUrl + fileName;
  
  loader.load(fileUrl, (gltf) => {
    // 处理当前加载的模型
    const model = gltf.scene;
    model.position.set(0, 0, 0);
    this.loadedModels.push(model); // 保存模型
    this.scene.add(model); // 添加到场景
    
    // 处理模型中的子对象
    model.traverse((child) => {
      if (child.isMesh) {
        if (this.objectNames.includes(child.name)) {
          this.objects.push(child);
          console.log('当前可以戳摸的模型', this.objects);
        }
        
        if (child.name === 'DR7_2') {
          this.DR7_2 = child;
        }
      }
    });
    
    // 加载下一个场景文件
    this.currentFileIndex++;
    this.loadNextFile(loader);
  }, 
    (xhr) => {
      this.$emit('loadingtextfn',`正在加载场景 ${fileName}: ${(xhr.loaded / xhr.total * 100)}%`)
    // 加载进度回调
  
  }, 
  (error) => {
    // 加载错误处理
    console.error(`加载 ${fileName} 出错:`, error);
    // 继续加载下一个文件
    this.currentFileIndex++;
    this.loadNextFile(loader);
  });
},

// 递归加载动画文件
loadNextAnimation(loader) {
  // 所有动画文件加载完成
  if (this.currentAnimationIndex >= this.dhfiles.length) {
    this.initAnimationComplete(); // 所有动画加载完成后执行
    this.animate();
    return;
  }
  
  // 获取当前要加载的动画文件名
  const animFileName = this.dhfiles[this.currentAnimationIndex];
  const animFileUrl = this.baseUrl + animFileName;
  
  loader.load(animFileUrl, (gltf) => {
    // this.destroyOldScene(false); // 保留场景，只清理旧动画
    
    if (this.worldOctree) {
      this.worldOctree.fromGraphNode(gltf.scene)
    }
    
    gltf.scene.position.set(0, 0, 0);
    
    // 处理动画模型中的特殊对象
    gltf.scene.children.forEach((item) => { 
      if (item.name == 'DH12') { 
        this.DH12 = item;
        this.DH12.visible = false;
      }
    });
      
    gltf.scene.traverse((child) => {
      if (child.isMesh) {
        child.castShadow = true;
        child.receiveShadow = true;
        
        if (this.objectNames.includes(child.name)) {
          this.objects.push(child);
        }
      }
    });
    
    this.scene.add(gltf.scene);
    this.loadedAnimations.push(gltf); // 保存加载的动画
    this.objectFather = gltf;
    this.andh = gltf.animations;
  // 
    this.animations = this.animations.concat(gltf.animations); // 合并所有动画
    console.log(`动画 ${animFileName} 加载完成`, gltf.animations);
    
    // 加载下一个动画文件
    this.currentAnimationIndex++;
    this.loadNextAnimation(loader);
  }, 
    (xhr) => {
    console.log('加载测试',xhr);
    
    // 动画加载进度回调
    this.$emit('loadingtextfn',`正在加载动画 ${animFileName}: ${(xhr.loaded / xhr.total * 100)}%`)
   
  }, 
  (error) => {
    // 动画加载错误处理
    console.error(`加载动画 ${animFileName} 出错:`, error);
    // 继续加载下一个动画
    this.currentAnimationIndex++;
    this.loadNextAnimation(loader);
  });
},

// 所有动画加载完成后执行的方法
initAnimationComplete() {
  this.$emit('loadingfn', false);
  console.log('所有场景和动画加载完成');
  console.log('合并后的动画数据', this.animations);
  
  // 可以在这里初始化动画控制器等
  // this.initAnimationController();
},

// 修改销毁方法，增加参数控制是否保留场景
destroyOldScene(removeScene = true) {
  if (removeScene && this.objectFather) {
    this.scene.remove(this.objectFather.scene);
  }
  // 清理其他需要清理的资源
  this.objects = [];
},
    updatePosition() {
      console.log('更新了平面位置及信息啦')
      // 更新顶部和底部平面的位置
      this.geometryTop.translate(
        this.params.topPlaneX,
        this.params.topPlaneY,
        this.params.topPlaneZ
      )
      this.geometryBottom.translate(
        this.params.bottomPlaneX,
        this.params.bottomPlaneY,
        this.params.bottomPlaneZ
      )
      // 重新渲染场景或者刷新应用程序
      this.animate()
    },



    // 6. 新增：初始化环境贴图的方法
    initEnvironment() {
        const loader = new CubeTextureLoader();
        // 这是 Three.js 编辑器中 "ROOM" 环境所使用的贴图资源
        // 资源来自 Three.js 官方 examples，通常是 Bridge2 场景
        const path = 'https://threejs.org/examples/textures/cube/Bridge2/';
        const format = '.jpg';
        const urls = [
            path + 'posx' + format, path + 'negx' + format,
            path + 'posy' + format, path + 'negy' + format,
            path + 'posz' + format, path + 'negz' + format
        ];
//  const cubeTexture = 
       loader.load(urls, (texture) => {
            // 可选：在加载完成后进行一些操作
            console.log('ROOM 环境贴图加载完成');
            // 将环境贴图应用到场景
            this.scene.background = texture;
            this.scene.environment = texture;
        }, undefined, (error) => {
            console.error('环境贴图加载失败:', error);
            // 如果加载失败，可以回退到简单的灯光方案
            this.initLight();
        });
    },

    //初始化灯光 (现在作为备用方案)
    initLight() {
       const ambientLight = new THREE.AmbientLight(0xffffff, 2)
       this.scene.add(ambientLight)
       const directionalLight1 = new THREE.DirectionalLight(0xffffff, 1.48)
    
       directionalLight1.position.set(14.897, -8.947, 13.458)
     //   directionalLight1.castShadow = true
       this.scene.add(directionalLight1)
       const directionalLight2 = new THREE.DirectionalLight(0xffffff, 0.38)
       directionalLight2.position.set(-20.184, -1.626, -12.484)
     //   directionalLight2.castShadow =  true
       this.scene.add(directionalLight2)
       const directionalLight3 = new THREE.DirectionalLight(0xffffff, 1.52)
       directionalLight3.position.set(-13.337, 0.317, 15.801)
     //   directionalLight3.castShadow = true
       this.scene.add(directionalLight3)
    },
    initPoint() {
      //初始换加载箭头指示图标
      const spriteImageLabel = (image) => {
        let textureLoader = new THREE.TextureLoader()
        const imageTexture = textureLoader.load(image)
        return imageTexture
      }
      let imgUrl = require('@/images/pointer.png')
      const spriteMap = spriteImageLabel(imgUrl)
      const spriteMaterial = new THREE.SpriteMaterial({
        map: spriteMap,
        color: 0xffffff
      })
      const sprite = new THREE.Sprite(spriteMaterial)
      sprite.scale.set(0.1, 0.1, 0.1)
      sprite.rotation.set(0, 0, Math.PI * 0.6)
      sprite.visible = false
      this.sprite = sprite
      this.scene.add(sprite)
    },
    // 根据按钮播放动画（使用全局唯一混合器）
playAction(animationName, realName) {
  console.log('播放了动画名称', animationName, '点击的物体', realName);
  this.playIng = true;

  // 关键：只创建一次混合器，复用已有的实例
  if (!this.theMixer) {
    this.theMixer = new THREE.AnimationMixer(this.objectFather.scene); // 全局唯一混合器
  }

  // 查找目标动画片段
  const clip = THREE.AnimationClip.findByName(this.objectFather.animations, animationName);
  if (!clip) {
    console.error(`未找到动画 ${animationName}`);
    return;
  }

  // 停止当前可能正在播放的动画（避免多动画冲突）
  if (this.action) {
    this.action.stop();
  }

  // 创建并配置动画Action
  const action = this.theMixer.clipAction(clip);
  action.loop = THREE.LoopOnce; // 只执行一次
  action.clampWhenFinished = true; // 播放完成后停在最后一帧
  action.play();

  // 更新状态
  this.action = action;
  this.currentAnimationName = animationName; // 记录当前动画名称（可选）

  // 监听动画完成事件
  this.theMixer.removeEventListener('finished', this.onAnimationFinished); // 先移除旧监听（避免重复）
  this.onAnimationFinished = () => {
    setTimeout(() => {
      this.playIng = false;
    
       this.$emit('clickItem',realName)
    }, 600);
  };
  this.theMixer.addEventListener('finished', this.onAnimationFinished);
},
    //循环渲染
    animate() {
      if (this.isDestroyed || !this.render) { 
        return
      }
      const deltaTime = this.clock.getDelta()
      if (this.theMixer) {
        //动画渲染  3000 控制动画没一帧之间的时长
        this.theMixer.update(deltaTime )
        // this.clock.getDelta()
      }
     this.animationFrameId= requestAnimationFrame(this.animate)
      this.render.render(this.scene, this.camera)
        this.rendererTop.render(this.scene, this.cameraTop);
  this.rendererSide.render(this.scene, this.cameraSide);
    },
    //镜头移动视角切换根据不同的步骤进行操作
    // move(position, rotation) {
    //   if (!this.camera) {
    //     return
    //   }
    //   // this.controls.enabled = false
    //   this.camera.position.set(position[0], position[1], position[2])
    //   this.camera.rotation.set(
    //     rotation[0] * Math.PI,
    //     rotation[1] * Math.PI,
    //     rotation[2] * Math.PI
    //   )
    //   this.camera.updateProjectionMatrix()
    // },
    // 改造后的 move 方法：支持指定相机
move(position, rotation, camera = this.camera) { // 默认操作第三视角相机
  if (!camera) return; // 确保相机存在

  // 设置位置
  camera.position.set(position[0], position[1], position[2]);
  // 设置旋转（注意：Three.js 旋转单位是弧度，这里保持原逻辑的 PI 转换）
  camera.rotation.set(
    rotation[0] * Math.PI,
    rotation[1] * Math.PI,
    rotation[2] * Math.PI
  );
  // 更新相机投影矩阵（位置/旋转变化后必须更新）
  camera.updateProjectionMatrix();
  console.log('更新相机',camera);
  
},
    //按照坐标位置显示指示箭头
    twinklePoint(x, y, z) {
      if (this.sprite != undefined) {
        this.sprite.visible = true
        this.sprite.position.set(x, y, z)
        this.spriteTimer = setInterval(() => {
          this.sprite.visible = !this.sprite.visible
          clearInterval(this.spriteTimer)
        }, 600) 
       
      }
    },
    getTextName(realName) {
      //根据模型名称返回对应汉字
      let textName = ''
      this.objectText.map((item) => {
        if (item.name == realName) {
          textName = item.text
        }
      })
      return textName
    },

    //获取名字
    getRealName(object) {
      //根据模型返回其父级group的名称，且之后在objects中存在的才会返回名称
      let objectNames = this.objectNames
      if (objectNames.includes(object.name)) {
        return object.name
      } else {
        if (object.parent) {
          return this.getRealName(object.parent)
        } else {
          return ''
        }
      }
    },
    //鼠标移动6+射线拾取
    onDocumentMouseMove(event) {
      //鼠标移动，用射线检测鼠标覆盖的东西，并弹出标识
      let maincontWidth = this.$el.offsetWidth
      let maincontHeight = this.$el.offsetHeight
      this.mouse.x = (event.offsetX / maincontWidth) * 2 - 1
      this.mouse.y = -(event.offsetY / maincontHeight) * 2 + 1
      this.raycaster.setFromCamera(this.mouse, this.camera)
      // console.log('当前检测到', this.objects)

      const intersections = this.raycaster.intersectObjects(this.objects)

      if (intersections.length > 0) {
        document.body.style.cursor = 'pointer'
        let textName = this.getTextName(
          this.getRealName(intersections[0].object)
        )
        this.tipShow = true
        this.tipPosition = {
          x: event.offsetX,
          y: event.offsetY
        }
        this.tipName = textName
      } else {
        document.body.style.cursor = 'initial'
        this.tipShow = false
        this.tipPosition = {
          x: event.offsetX,
          y: event.offsetY
        }
        this.tipName = ''
        this.selectedObjects = []
      }
    },

    //清除指示箭头
    clearPoint() {
      console.log('清楚箭头', this.sprite.visible)
      if (this.sprite) {
        console.log('清楚箭头', this.sprite.visible)
        this.sprite.visible = false
      }
      if (this.spriteTimer) {
        clearInterval(this.spriteTimer)
        this.spriteTimer = null
      }
    },
    //鼠标按下播放动画
    onDocumentMouseDown(event) {
      //鼠标移动，用射线检测鼠标覆盖的东西，并弹出标识

      let maincontWidth = this.$el.offsetWidth
      let maincontHeight = this.$el.offsetHeight
      this.mouse.x = (event.offsetX / maincontWidth) * 2 - 1
      this.mouse.y = -(event.offsetY / maincontHeight) * 2 + 1
      this.raycaster.setFromCamera(this.mouse, this.camera)
      const intersections = this.raycaster.intersectObjects(this.objects)
      if (intersections.length > 0) {
        document.body.style.cursor = 'pointer'
        if (intersections[0].object.name == this.jcname) {
          // this.addOutinesss('')
          document.exitPointerLock()
        }
        this.clickAfter(intersections[0].object.name)
      }
      if (document.pointerLockElement) {
        event.preventDefault()
      } else {
        // if (this.setp == 1.2 || this.setp == 1.3) {
        //   if (event.target.localName == 'canvas') {
        //     document.body.requestPointerLock()
        //   }
        // }
      }
    },
    //根据点击的模型播放动画
    clickAfter(realName) {
      console.log('当前点击的模型', realName)
   
      // 动画还没加载完的情况
      if (!this.andh) {
        console.log('当前没有动画数据')
        if (this.action) {
          this.action.stop()
          this.action.paused = true
        }
        this.action = null
        return
      }
      if (this.playIng) {
        // this.step
        if (!this.playIng) {
          console.log('当前任务还未完成禁止下一个')
        } else {
          return
        }
      }
    
       this.twinklePoint(-666, -666, -666)
      let animationName = ''
      if (realName == 'DR8_1' && this.taskids == 2) {
        animationName = '5'
        this.playIng = true
      }
         if ((realName == 'TanCeQi4'||realName=='DR8_1') && this.taskids == 4.1) {
        animationName = '6'
        this.playIng = true
         }
       if ((realName == 'DR8_1'  || realName == 'BiJiBenDianNao1') && this.taskids == 8) {
      this.clickItem('DR8_1')
      }
      // 
      if (!animationName) {
        // console.log('dh')
        return
      }

       this.clearPoint()
      this.playAction(animationName, realName)
    },
/**
 * 将指定动画设置为完成状态并停留在最后一帧
 * 参考stopall()逻辑，不使用stop()避免回退到第一帧
 * @param {string} targetAnimName - 目标动画名称
 * @returns {boolean} 操作成功返回true，失败返回false
 */
setAnimFinishedAndStayLastFrame(targetAnimName) {
    // 基础参数校验
    if (typeof targetAnimName !== 'string' || targetAnimName.trim() === '') {
        console.error('无效动画名称：必须是非空字符串');
        return false;
    }

    // 检查是否有动画资源
    if (!this.objectFather?.animations?.length) {
        console.error('没有可用的动画资源');
        return false;
    }

    // 确保混合器存在
    if (!this.theMixer) {
        console.log('初始化动画混合器...');
        this.theMixer = new THREE.AnimationMixer(this.objectFather.scene);
    }

    // 查找目标动画片段
    const targetClip = THREE.AnimationClip.findByName(
        this.objectFather.animations,
        targetAnimName
    );
    if (!targetClip) {
        console.error(`未找到名称为 "${targetAnimName}" 的动画片段`);
        return false;
    }

    // 停止当前正在播放的动画（复用stopall的停止逻辑）
    if (this.action && this.action.isRunning()) {
        this.action.clampWhenFinished = true;
        this.playIng = false;
        if (this.action._clip && this.action._clip.name) {
            this.animationStatus[this.action._clip.name] = true;
        }
        if (this.action._clip) {
            this.action.time = this.action._clip.duration;
            this.action.paused = true;
            this.theMixer.update(0);
        }
        // 不调用stop()，避免状态重置
    }
    // 获取目标动画的Action并配置
    const targetAction = this.theMixer.clipAction(targetClip);
    // 核心逻辑：参考stopall()的停止策略
    targetAction.clampWhenFinished = true; // 锁定最后一帧
    targetAction.setLoop(THREE.LoopOnce);
    // 关键：先播放再立即暂停在最后一帧（模拟播放完成状态）
    targetAction.play(); // 启动动画状态机
    targetAction.time = targetClip.duration; // 跳转到最后一帧
    targetAction.paused = true; // 暂停在最后一帧
    this.theMixer.update(0); // 强制刷新画面
    // 更新状态管理
    this.animationStatus = this.animationStatus || {};
    this.animationStatus[targetAnimName] = true;
    this.playIng = false;
    this.action = targetAction;
    console.log(`动画 "${targetAnimName}" 已设置为完成状态并停留在最后一帧`);
    return true;
}  
  }
}

function createAreaLightMaterial( intensity ) {

	// create an emissive-only material. see #31348
	const material = new MeshLambertMaterial( {
		color: 0x000000,
		emissive: 0xffffff,
		emissiveIntensity: intensity
	} );

	return material;

}



class RoomEnvironment extends THREE.Scene {

	constructor() {
  

    super();

		const geometry = new BoxGeometry();
		geometry.deleteAttribute( 'uv' );

		const roomMaterial = new MeshStandardMaterial( { side: BackSide } );
		const boxMaterial = new MeshStandardMaterial();

		const mainLight = new PointLight( 0xffffff, 900, 28, 2 );
		mainLight.position.set( 0.418, 16.199, 0.300 );
		this.add( mainLight );

		const room = new Mesh( geometry, roomMaterial );
		room.position.set( - 0.757, 13.219, 0.717 );
		room.scale.set( 31.713, 28.305, 28.591 );
		this.add( room );

		const boxes = new InstancedMesh( geometry, boxMaterial, 6 );
		const transform = new Object3D();

		// box1
		transform.position.set( - 10.906, 2.009, 1.846 );
		transform.rotation.set( 0, - 0.195, 0 );
		transform.scale.set( 2.328, 7.905, 4.651 );
		transform.updateMatrix();
		boxes.setMatrixAt( 0, transform.matrix );

		// box2
		transform.position.set( - 5.607, - 0.754, - 0.758 );
		transform.rotation.set( 0, 0.994, 0 );
		transform.scale.set( 1.970, 1.534, 3.955 );
		transform.updateMatrix();
		boxes.setMatrixAt( 1, transform.matrix );

		// box3
		transform.position.set( 6.167, 0.857, 7.803 );
		transform.rotation.set( 0, 0.561, 0 );
		transform.scale.set( 3.927, 6.285, 3.687 );
		transform.updateMatrix();
		boxes.setMatrixAt( 2, transform.matrix );

		// box4
		transform.position.set( - 2.017, 0.018, 6.124 );
		transform.rotation.set( 0, 0.333, 0 );
		transform.scale.set( 2.002, 4.566, 2.064 );
		transform.updateMatrix();
		boxes.setMatrixAt( 3, transform.matrix );

		// box5
		transform.position.set( 2.291, - 0.756, - 2.621 );
		transform.rotation.set( 0, - 0.286, 0 );
		transform.scale.set( 1.546, 1.552, 1.496 );
		transform.updateMatrix();
		boxes.setMatrixAt( 4, transform.matrix );

		// box6
		transform.position.set( - 2.193, - 0.369, - 5.547 );
		transform.rotation.set( 0, 0.516, 0 );
		transform.scale.set( 3.875, 3.487, 2.986 );
		transform.updateMatrix();
		boxes.setMatrixAt( 5, transform.matrix );

		this.add( boxes );


		// -x right
		const light1 = new Mesh( geometry, createAreaLightMaterial( 50 ) );
		light1.position.set( - 16.116, 14.37, 8.208 );
		light1.scale.set( 0.1, 2.428, 2.739 );
		this.add( light1 );

		// -x left
		const light2 = new Mesh( geometry, createAreaLightMaterial( 50 ) );
		light2.position.set( - 16.109, 18.021, - 8.207 );
		light2.scale.set( 0.1, 2.425, 2.751 );
		this.add( light2 );

		// +x
		const light3 = new Mesh( geometry, createAreaLightMaterial( 17 ) );
		light3.position.set( 14.904, 12.198, - 1.832 );
		light3.scale.set( 0.15, 4.265, 6.331 );
		this.add( light3 );

		// +z
		const light4 = new Mesh( geometry, createAreaLightMaterial( 43 ) );
		light4.position.set( - 0.462, 8.89, 14.520 );
		light4.scale.set( 4.38, 5.441, 0.088 );
		this.add( light4 );

		// -z
		const light5 = new Mesh( geometry, createAreaLightMaterial( 20 ) );
		light5.position.set( 3.235, 11.486, - 12.541 );
		light5.scale.set( 2.5, 2.0, 0.1 );
		this.add( light5 );

		// +y
		const light6 = new Mesh( geometry, createAreaLightMaterial( 100 ) );
		light6.position.set( 0.0, 20.0, 0.0 );
		light6.scale.set( 1.0, 0.1, 1.0 );
		this.add( light6 );

	}

	/**
	 * Frees internal resources. This method should be called
	 * when the environment is no longer required.
	 */
	dispose() {

		const resources = new Set();

		this.traverse( ( object ) => {

			if ( object.isMesh ) {

				resources.add( object.geometry );
				resources.add( object.material );

			}

		} );

		for ( const resource of resources ) {

			resource.dispose();

		}

	}

}

